﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using iWare.Wms.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;

namespace iWare.Wms.Application
{
    /// <summary>
    /// 容器服务
    /// </summary>
    [Route("api/WareContainer")]
    [ApiDescriptionSettings("仓库基础数据", Name = "Container", Order = 100)]

    public class WareContainerService : ControllerBase, IDynamicApiController, ITransient
    {
        private readonly IRepository<WareContainer, MasterDbContextLocator> _wareContainerRep; //容器仓储
        private readonly IRepository<WareArea, MasterDbContextLocator> _wareAreaRep; //所属库区仓储

        #region 默认
        /// <summary>
        /// 默认
        /// </summary>
        /// <param name="wareContainerRep"></param>
        /// <param name="wareAreaRep"></param>
        public WareContainerService(
            IRepository<WareArea, MasterDbContextLocator> wareAreaRep,
            IRepository<WareContainer, MasterDbContextLocator> wareContainerRep
        )
        {
            _wareContainerRep = wareContainerRep;
            _wareAreaRep = wareAreaRep;
        }
        #endregion

        /// <summary>
        /// 分页查询容器
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("page")]
        public async Task<PageResult<WareContainerOutput>> Page([FromQuery] WareContainerSearch input)
        {
            var result = await _wareContainerRep.DetachedEntities
                .Where(input.AreaID > 0, u => u.AreaID == input.AreaID)
                .Where(input.IsVirtual != YesOrNot.All, u => u.IsVirtual == input.IsVirtual)
                .Where(!string.IsNullOrEmpty(input.Parameter1) && input.Parameter1 != "ALL", u => u.Parameter1 == input.Parameter1)
                .Where(!string.IsNullOrEmpty(input.Parameter2) && input.Parameter2 != "ALL", u => u.Parameter2 == input.Parameter2)
                .Where(!string.IsNullOrEmpty(input.Code), u => EF.Functions.Like(u.Code, $"%{input.Code.Trim()}%"))
                .Where(input.ContainerStatus != null && input.ContainerStatus != ContainerStatusEnum.all, u => u.ContainerStatus == input.ContainerStatus)
                .OrderBy(PageInputOrder.OrderBuilder<WareContainerSearch>(input))
                .Where(!string.IsNullOrEmpty(input.SearchBeginTime), u => u.CreatedTime >= DateTime.Parse(input.SearchBeginTime.Trim()) &&
                 u.CreatedTime <= DateTime.Parse(input.SearchEndTime.Trim()))
                .ProjectToType<WareContainerOutput>()
                .ToADPagedListAsync(input.PageNo, input.PageSize);

            foreach (var item in result.Rows)
            {
                var areaModel = await _wareAreaRep.FirstOrDefaultAsync(n => n.Id == item.AreaID);
                if (areaModel != null) item.AreaName = areaModel.AreaName;
            }

            return result;
        }

        /// <summary>
        /// 新增容器表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task Add([FromBody] AddWareContainerInput input)
        {
            var isExist = await _wareContainerRep.DetachedEntities.AnyAsync(u => u.Code == input.Code);
            if (isExist) throw Oops.Oh("数据已存在");

            var wareContainer = input.Adapt<WareContainer>();
            await _wareContainerRep.InsertAsync(wareContainer);
        }

        /// <summary>
        /// 删除容器表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("delete")]
        public async Task Delete([FromBody] DeleteWareContainerInput input)
        {
            int length = input.Id.Count;
            for (int i = 0; i < length; i++)
            {
                long Id = input.Id[i];
                var wareContainer = await _wareContainerRep.FirstOrDefaultAsync(u => u.Id == Id);
                await _wareContainerRep.DeleteAsync(wareContainer);
            }
        }

        /// <summary>
        /// 更新容器表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("edit")]
        public async Task Update([FromBody] UpdateWareContainerInput input)
        {
            var isExist = await _wareContainerRep.AnyAsync(u => u.Id == input.Id, false);
            if (!isExist) throw Oops.Oh("数据不存在");

            var wareContainer = input.Adapt<WareContainer>();
            await _wareContainerRep.UpdateAsync(wareContainer, ignoreNullValues: true);
        }

        /// <summary>
        /// 根据条件只查询未使用中的容器
        /// </summary>
        /// <returns></returns>
        [HttpGet("conatinerList")]
        public async Task<List<WareContainerByStatusOutput>> ConatinerList()
        {
            return await _wareContainerRep
                .Where(t => t.ContainerStatus == ContainerStatusEnum.kongxian)
                .ProjectToType<WareContainerByStatusOutput>().ToListAsync();
        }

        /// <summary>
        /// 系统生成木制容器500个
        /// </summary>
        /// <returns></returns>
        [HttpGet("createContainer")]
        public async Task CreateContainer()
        {
            for (int i = 1; i <= 500; i++)
            {
                var itemcode = "00000";
                if (i < 10)
                {
                    itemcode = "0000" + i;
                }
                else if (i < 100)
                {
                    itemcode = "000" + i;
                }
                else if (i < 1000)
                {
                    itemcode = "00" + i;
                }
                else if (i < 10000)
                {
                    itemcode = "0" + i;
                }
                else
                {
                    itemcode = i.ToString();
                }
                var code = "P-" + "TM" + itemcode;

                var containerModel = new WareContainer()
                {
                    Code = code,
                    AreaID = 374444736143429,
                    Parameter1 = "T",
                    Parameter2 = "M",
                    IsVirtual = YesOrNot.N,
                    ContainerStatus = ContainerStatusEnum.kongxian,
                };
                var exit = await _wareContainerRep.AnyAsync(n => n.Code == code);
                if (!exit)
                {
                    await _wareContainerRep.InsertAsync(containerModel, true);
                }
            }
        }

        /// <summary>
        /// 系统生成南京虚拟容器1000个
        /// </summary>
        /// <returns></returns>
        [HttpGet("NJContainer")]
        public async Task NJContainer()
        {
            for (int i = 1; i <= 1000; i++)
            {
                var itemcode = "00000";
                if (i < 10)
                {
                    itemcode = "0000" + i;
                }
                else if (i < 100)
                {
                    itemcode = "000" + i;
                }
                else if (i < 1000)
                {
                    itemcode = "00" + i;
                }
                else if (i < 10000)
                {
                    itemcode = "0" + i;
                }
                else
                {
                    itemcode = i.ToString();
                }
                var code = "NJ" + itemcode;

                var containerModel = new WareContainer()
                {
                    Code = code,
                    AreaID = 405972997394501,
                    Parameter1 = "Q",
                    Parameter2 = "Q",
                    IsVirtual = YesOrNot.Y,
                    ContainerStatus = ContainerStatusEnum.kongxian,
                };
                var exit = await _wareContainerRep.AnyAsync(n => n.Code == code);
                if (!exit)
                {
                    await _wareContainerRep.InsertAsync(containerModel, true);
                }
            }
        }
    }
}
